home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1997
/
MacHack 1997.toast
/
Hacks
/
Hacks ’95
/
Venus
/
FractalMap.cc
< prev
next >
Wrap
C/C++ Source or Header
|
1995-06-23
|
5KB
|
128 lines
// This may look like C code, but it is really -*- C++ -*-
/*
************************************************************************
*
* Generating Fractal Maps
*
* We use the following algorithm described in the "documentation" to
* program MARS (Tim Clarke, tjc1005@hermes.cam.ac.uk, posted in some "games"
* group)
*
* "This is a recursive subdivision, or plasma, fractal. You start of
* with a random height at (0,0) and therefore also at (256,0), (0,256),
* (256,256). Call a routine that takes as input the size and position
* of a square, in the first case the entire map.
* This routine get the heights from the corners of the square it gets
* given. Across each edge (if the map has not been written to at the
* point halfway along that edge), it takes the average of the heights of
* the 2 corners on that edge, applies some noise proportional to the
* length of the edge, and writes the result into the map at a position
* halfway along the edge. The center of the square is the average of the
* four corners+noise.
* The routine then calls itself recursively, splitting each square into
* four quadrants, calling itself for each quadrant until the length of
* the side is 2 pixels.
* This is probably old-hat to many people, but the map is made more
* realistic by blurring [applying some filter to it]
* The colors are done so that the sun is on the horizon to the East:
* Color=A*[ w(u+1,v)-w(u,v) ]+B
* with A and B chosen so that the full range of the palette is used.
* The sky is a similar fractal but without the colour transformation"
* <EOQ>
*
* Again, one can achieve this effect by applying an appropriate filter.
* In principle, the filter for blurring and the filter for coloring
* (the latter looks like a simple gradient/edge enhancement filter)
* can be combined in a single one.
*
* In the present program, we use an iterative rather than recursive
* procedure.
*
************************************************************************
*/
#include "std.h"
#include "image.h"
#include "myenv.h"
// Fractal "cloud"
class FractalMap : public IMAGE
{
void make_fractal_map(const int scale);
public:
FractalMap(const int dimension);
~FractalMap(void) {}
void display(const char * title) const;
};
// Construng a fractal "cloud"
FractalMap::FractalMap(const int dimension) : IMAGE(dimension,dimension,8)
{
(*this)(0,0) = 128; // Seed
register int scale;
for(scale=dimension; scale>1; scale >>= 1)
make_fractal_map(scale);
}
// Get some noise with a dispersion 'scale'
// (which is assumed to be a power of 2)
// and average 0
// Say, if scale=2 return either 0 or 1
// if scale=128, return the random number
// within [-64,63]
// Note, that usually a couple of low-order
// bits of Random() are "less" random; therefore,
// we shift them out.
static int get_noise(const int scale)
{
return ((Random() >> 2) & (scale/2-1)) - scale/4;
}
// Make the fractal map at a specified scale
// Keep in mind "wrap-around" property of
// the map
void FractalMap::make_fractal_map(const int scale)
{
register int i, j;
for(i=0; i<q_nrows(); i += scale)
for(j=0; j<q_ncols(); j += scale)
{
int i_up = i+scale; if( i_up >= q_nrows() ) i_up-=q_nrows();
int j_up = j+scale; if( j_up >= q_ncols() ) j_up-=q_ncols();
int i_hp = i+scale/2; if( i_hp >= q_nrows() ) i_hp-=q_nrows();
int j_hp = j+scale/2; if( j_hp >= q_ncols() ) j_hp-=q_ncols();
int corner00 = (*this)(i,j);
int corner10 = (*this)(i_up,j);
int corner01 = (*this)(i,j_up);
int corner11 = (*this)(i_up,j_up);
//message("i %d, j%d, scale %d Corners %d %d %d %d",i,j,scale,corner00,corner01,corner10,corner11);
int mid30 = (*this)(i_hp,j) = (corner00+corner10)/2 + get_noise(scale);
int mid03 = (*this)(i,j_hp) = (corner00+corner01)/2 + get_noise(scale);
int mid31 = (*this)(i_hp,j_up) = (corner01+corner11)/2 + get_noise(scale);
int mid13 = (*this)(i_up,j_hp) = (corner10+corner11)/2 + get_noise(scale);
(*this)(i_hp,j_hp) = (mid30+mid03+mid31+mid13)/4 + get_noise(scale);
}
}
void project_3D(const IMAGE& image, const char * title);
void main(void)
{
Initialize_MAC();
GetDateTime((unsigned long *)&qd.randSeed);
Random(); Random(); Random(); Random(); // Just randomizing
FractalMap map(256);
map.clip_to_intensity_range();
// map.invert();
// map.write_pgm("map.pgm");
project_3D(map,"map");
// display_map(map,"map");
}